이것은 C 라이브러리 함수를 호출하여 수행하는 방법을 묻기 때문에 essentially a duplicate of this C/C++ question입니다. 괜찮습니다. 당신이 asm에서 그렇게 할 수있는 이유가 없습니다. 나는 그것을 단지 정확하게하는 방법에 대해 말할만큼 충분하기 때문에 복제본으로 그냥 닫지 않기로 결정했다.
C 구문을 사용하면 함께 붙일 필요가있는 함수를 쉽게 표현할 수 있으므로 기본적으로 C로 대답 할 것입니다. asm에서 루프를 사용하여 단계를 수행하려면 해당 단계를 수행하십시오. 이진 문자열을 정수로 변환하는 것은 매우 쉽습니다. 한 번에 하나씩 숫자를 변경하면됩니다. (또는 SSE2 pmovmskb
을 사용하십시오).
출력을 기본 8로 인쇄하려면 %o
출력을 사용하십시오. 이는 ISO C에서 직접 지원됩니다.
Base 2 isn't, though. 그러나 strtoul
은 선택한 기수로 문자열 -> 부호없는 정수를 변환합니다. 유일한 문제는 입력을 문자열로 읽는 것입니다. 이를 수행하는 데는 여러 가지 방법이 있지만 2 진수가 아닌 문자를 과도하게 읽고 소비하지 않으려면 scanf
에 0과 1 문자 만 허용하는 %[]
변환을 사용할 수 있습니다.
// optionally this buffer could be static like your `number`, but there's no reason to do that.
char buf[65]; // reserve 65 bytes on the stack with sub esp, 80 (rounded up to keep stack 16B-aligned)
buf[0] = 0; // NULL terminate our stack buffer to avoid crashing in strtoul if scanf doesn't convert anything.
int success = scanf(" %64[01]", buf); // skip optional whitespace and store up to 64 bytes + null terminator into buf
// optional: check the conversion.
unsigned long num = strtoul(buf, NULL, 2); // parse as base 2, returning a binary integer
printf("%lo\n", num); // print as octal
// or %o if int and long are the same width in 32-bit asm
이 C 문의 모든 ASM 지침이 아니라 루프의 짧은 블록으로 구현 될 수있다
그래서 당신은 다음과 같습니다 ASM을 작성할 수 있습니다. 방법을 모르는 경우 ask a compiler with gcc -O2 -S -masm=intel
.
길이 제한이 scanf
형식 문자열이므로 사용자가 키를 누르고 있고 프로그램이 1
의 1000 바이트를 읽으면 버퍼 오버플로가 발생하지 않습니다.
현재 stdin
버퍼에있는 공백을 건너 뛰려면 형식 문자열의 선행 공백을 주목하십시오. (예 : scanf
이 일반적으로 사용하지 않는 이전 줄 끝의 개행). Conversions like %c
and %[
don't skip leading whitespace on their own.
후행하지 않는 문자를 소비하려면 %64s
을 사용하십시오. strtoul
은 첫 번째 비 숫자 문자에서 멈출 것입니다. (그리고 NULL이 아닌 포인터를 두 번째 인수로 전달하면 그 위치에 대한 포인터를 저장합니다.
이것은 단지 C 라이브러리 함수를 호출하는 것입니다. 이것은 변환의 "구현"이 아닙니다. 충분하다면, 8 진수에는 포맷터'% o'가 있습니다. 바이너리의 경우 놀랍게도 아무 것도 보이지 않으므로, 당신은'scanf' 문서를 가지고 있는지 확인해야합니다. 그럼에도 불구하고 이것은 아주 초보적인 것입니다. 숫자 체계 뒤에있는 수학을 이해한다면 종이 + 펜의 모든 기초를 쉽게 변환 할 수 있어야합니다. 그런 다음 어셈블리에서 이러한 수학 연산을 수행하는 것이 일반적으로 쉽습니다. 특히 두 개의 기본 연산이 포함 된 경우 비트 값을 다시 정렬해야합니다. – Ped7g
즉, 기본 2의 입력은 입력 요소 당 1 개의 중요한 비트를가집니다. (ASCII 문자열이 "010101"인 경우 가장 낮은 것을 제외한 모든 비트에서 각 문자를 제외 할 수 있으며 이진 입력입니다. ASCII ''0 ''은 0011_0000입니다. 그리고 '1'은 '0011_0001'이므로, 문자열 입력의 마지막 비트는 0, 1, 0, 1, 0, 1 ...)이 될 것입니다.8 진수 출력은 한 자리 당 3 비트가 필요하므로 '010', '101'로 그룹화하고이 두 값, 즉 '25'를 출력하면됩니다. ... 나누기/곱셈은 필요하지 않습니다 (어떤 형식의 곱셈/나누기가 발생하는 기본 10 형식과 달리). '0b010101 == 0o25' – Ped7g
@ Ped7g : ISO C scanf/printf [기본 2 변환 지정자가 없습니다.] (https://stackoverflow.com/questions/11597863/why-does-scanfi-a-not-take- binary-like-0b101)이며 표준 확장이 아니며 [glibc에서도] (https://stackoverflow.com/a/112947/224132)도 아닙니다. 입력을 위해서,'strtol'은 arg로 기수를 취합니다. –