I wanted to see what happens behind the scenes when unsigned long long was assigned the value unsigned int . I made a simple C ++ program to try and move everything from the main ():
#include <iostream> #include <stdlib.h> void usage() { std::cout << "Usage: ./u_to_ull <unsigned int>\n"; exit(0); } void atoiWarning(int foo) { std::cout << "WARNING: atoi() returned " << foo << " and (unsigned int)foo is " << ((unsigned int)foo) << "\n"; } void result(unsigned long long baz) { std::cout << "Result as unsigned long long is " << baz << "\n"; } int main(int argc, char** argv) { if (argc != 2) usage(); int foo = atoi(argv[1]); if (foo < 0) atoiWarning(foo); // Signed to unsigned unsigned int bar = foo; // Conversion unsigned long long baz = -1; baz = bar; result(baz); return 0; }
The resulting assembly produced this for the main:
0000000000400950 <main>: 400950: 55 push %rbp 400951: 48 89 e5 mov %rsp,%rbp 400954: 48 83 ec 20 sub $0x20,%rsp 400958: 89 7d ec mov %edi,-0x14(%rbp) 40095b: 48 89 75 e0 mov %rsi,-0x20(%rbp) 40095f: 83 7d ec 02 cmpl $0x2,-0x14(%rbp) 400963: 74 05 je 40096a <main+0x1a> 400965: e8 3a ff ff ff callq 4008a4 <_Z5usagev> 40096a: 48 8b 45 e0 mov -0x20(%rbp),%rax 40096e: 48 83 c0 08 add $0x8,%rax 400972: 48 8b 00 mov (%rax),%rax 400975: 48 89 c7 mov %rax,%rdi 400978: e8 0b fe ff ff callq 400788 < atoi@plt > 40097d: 89 45 f0 mov %eax,-0x10(%rbp) 400980: 83 7d f0 00 cmpl $0x0,-0x10(%rbp) 400984: 79 0a jns 400990 <main+0x40> 400986: 8b 45 f0 mov -0x10(%rbp),%eax 400989: 89 c7 mov %eax,%edi 40098b: e8 31 ff ff ff callq 4008c1 <_Z11atoiWarningi> 400990: 8b 45 f0 mov -0x10(%rbp),%eax 400993: 89 45 f4 mov %eax,-0xc(%rbp) 400996: 48 c7 45 f8 ff ff ff movq $0xffffffffffffffff,-0x8(%rbp) 40099d: ff 40099e: 8b 45 f4 mov -0xc(%rbp),%eax 4009a1: 48 89 45 f8 mov %rax,-0x8(%rbp) 4009a5: 48 8b 45 f8 mov -0x8(%rbp),%rax 4009a9: 48 89 c7 mov %rax,%rdi 4009ac: e8 66 ff ff ff callq 400917 <_Z6resulty> 4009b1: b8 00 00 00 00 mov $0x0,%eax 4009b6: c9 leaveq 4009b7: c3 retq
-1 from C ++ makes it clear that -0x8(%rbp) matches baz (due to $0xffffffffffffffff ). -0x8(%rbp) written to %rax , but the top four bytes of %rax did not seem to be assigned, %eax was assigned
Does this mean that the top 4 bytes of -0x8(%rbp) are undefined?
source share